/*
 *    Copyright (c) 2018-2025, cloud All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: cloud
 */
package com.fuyao.cloud.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.admin.api.dto.SysNumberDTO;
import com.fuyao.cloud.admin.api.entity.SysServerNumber;
import com.fuyao.cloud.admin.mapper.SysServerNumberMapper;
import com.fuyao.cloud.admin.service.SysServerNumberService;
import com.fuyao.cloud.common.data.resolver.ParamResolver;
import com.google.common.collect.Maps;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * 扶摇编码生成类
 *
 * @author liyue
 * @date 2021-11-15 09:56:07
 */
@Service
public class SysServerNumberServiceImpl extends ServiceImpl<SysServerNumberMapper, SysServerNumber> implements SysServerNumberService {

	@Override
	public Long getServerNumber(SysNumberDTO sysNumberDTO) {
		String type = sysNumberDTO.getNumbertype();
		String code = sysNumberDTO.getCode();
		SysServerNumber sysServerNumber = this.baseMapper.selectOne(Wrappers.<SysServerNumber>lambdaQuery().select().eq(SysServerNumber::getNumbertype, type).eq(SysServerNumber::getCode, code));
		if (!ObjectUtils.isEmpty(sysServerNumber)) {
			Long value = sysServerNumber.getValue();
			sysServerNumber.setValue(value + 1);
			this.baseMapper.updateById(sysServerNumber);
			return sysServerNumber.getValue();
		}
		SysServerNumber saveServerNumber = new SysServerNumber();
		saveServerNumber.setNumbertype(type);
		saveServerNumber.setCode(code);
		saveServerNumber.setValue(1L);
		this.save(saveServerNumber);
		return saveServerNumber.getValue();
	}

	@Override
	public String getServerNumberStr(SysNumberDTO sysNumberDTO) {
		String type = sysNumberDTO.getNumbertype();
		String code = sysNumberDTO.getCode();
		Long num = getNum(sysNumberDTO);
		SysServerNumber sysServerNumber = this.baseMapper.selectOne(Wrappers.<SysServerNumber>lambdaQuery().select().eq(SysServerNumber::getNumbertype, type).eq(SysServerNumber::getCode, code));
		if (!ObjectUtils.isEmpty(sysServerNumber)) {
			Long value = sysServerNumber.getValue();
			sysServerNumber.setValue(value);
			this.baseMapper.updateById(sysServerNumber);
			return getNumberStr(sysServerNumber.getParentCode(), sysServerNumber.getCode(), sysServerNumber.getValue(), num);
		}
		SysServerNumber saveServerNumber = new SysServerNumber(type, code, 1L);
		this.save(saveServerNumber);
		return getNumberStr(saveServerNumber.getParentCode(), saveServerNumber.getCode(), saveServerNumber.getValue(), num);
	}

	@Override
	public String getServerNumberJoinParent(SysNumberDTO sysNumberDTO) {
		String type = sysNumberDTO.getNumbertype();
		String code = sysNumberDTO.getCode();
		Long num = getNum(sysNumberDTO);
		String parentCode = sysNumberDTO.getParentCode();
		SysServerNumber sysServerNumber = this.baseMapper.selectOne(Wrappers.<SysServerNumber>lambdaQuery().
				select().eq(SysServerNumber::getNumbertype, type)
				.eq(SysServerNumber::getCode, code)
				.eq(SysServerNumber::getParentCode, parentCode));

		if (!ObjectUtils.isEmpty(sysServerNumber)) {
			Long value = sysServerNumber.getValue();
			sysServerNumber.setValue(value + 1);
			this.baseMapper.updateById(sysServerNumber);
			return getNumberStr(sysServerNumber.getParentCode(), sysServerNumber.getCode(), sysServerNumber.getValue(), num);
		}
		SysServerNumber saveServerNumber = new SysServerNumber(type, code, 1L);
		this.save(saveServerNumber);
		return getNumberStr(saveServerNumber.getParentCode(), saveServerNumber.getCode(), saveServerNumber.getValue(), num);
	}

	@Override
	public Map<String,String> getNumberMap(SysNumberDTO sysNumberDTO){
		HashMap<String, String> resultMap = Maps.newHashMap();
		Long value = this.getServerNumber(sysNumberDTO);
		String formatStr = String.format("%0" + sysNumberDTO.getNum() + "d", value);
		resultMap.put("value",String.valueOf(value));
		resultMap.put("code", formatStr);
		resultMap.put("codeValue",this.getServerNumberStr(sysNumberDTO));
		return resultMap;
	}

	/**
	 * 组装编码 parentCode.Code.format格式  例：XX.XX.000001
	 *
	 * @param parentCode 父级编码
	 * @param code       编码
	 * @param value      格式化数值 。
	 * @param num        格式化长度
	 * @return 编码。
	 */
	private String getNumberStr(String parentCode, String code, Long value, Long num) {
		StringBuilder resultStr = new StringBuilder();
		if (StrUtil.isNotEmpty(parentCode)) {
			resultStr.append(parentCode).append(".");
		}
		resultStr.append(code);
		String formatStr = String.format("%0" + num + "d", value);
		resultStr.append(formatStr);
		return resultStr.toString();
	}



	/**
	 * 获取格式化位数
	 *
	 * @param sysNumberDTO
	 * @return
	 */
	private Long getNum(SysNumberDTO sysNumberDTO) {
		return ObjectUtils.isEmpty(sysNumberDTO.getNum()) ? ParamResolver.getLong("NUMBER_AUTO_BIT", 6L) : sysNumberDTO.getNum();
	}
}
